package com.yc.http.tomcat.impl;

import com.yc.http.tomcat.Cookie;
import com.yc.http.tomcat.HttpServletRequest;
import com.yc.http.tomcat.HttpSession;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpServletRequestImpl implements HttpServletRequest {

    private InputStream in;
    // 头行参数
    private String method, requestURI, protocol;
    // 头域参数集合
    private Map<String,String> headerMap = new HashMap<>();
    private String queryString;

    private Map<String, List<String>> paramMap = new HashMap<>();

    public HttpServletRequestImpl(Socket socket) throws IOException {
        in = socket.getInputStream();
        String line;
        for (int i = 0; ; i++) {
            line = readLine(in);
            System.out.println(line);
            // 读到空行则退出
            if (line.isEmpty()) {
                break;
            }
            if (i == 0) {
                // 请求头行
                String[] items = line.split(" ");
                method = items[0];
                requestURI = items[1];
                protocol = items[2];

                if(requestURI.contains("?")){
                    items = requestURI.split("\\?");
                    requestURI = items[0];
                    queryString = items[1];
                    if(queryString!=null&&queryString.length()>0){
                        parseFormParam(queryString);
                    }
                }
            } else {
                String[] items = line.split(": ");
                headerMap.put(items[0], items[1]);
            }
        }
        if("POST".equals(method)){
            String length = headerMap.get("Content-Length");
            int size = Integer.parseInt(length);
            StringBuilder body = new StringBuilder();
            for (int i = 0; i < size; i++) {
                char c = (char) in.read();
                body.append(c);
            }
            parseFormParam(body.toString());
            System.out.println(body);
        }
        //System.out.println(this);

        // 从请求中获取会话 ID
        Cookie[] cookies = this.getCookies();
        String sessionId = null;
        if(cookies!=null){
            for (Cookie cookie : cookies) {
                if(cookie.getName().equals("JSESSIONID")){
                    sessionId = cookie.getValue();
                }
            }
        }
        // 从容器中获取会话id
        session = HttpSessionImpl.sessionMap.get(sessionId);
        // 如果容器中没有对应的会话对象, 则创建新的会话
        if(session==null){
            session = new HttpSessionImpl();
        }
    }
    private HttpSession session;

    /**
     * 解析表单格式参数
     * @param paramStr  格式: a=1&b=2&c=3...
     */
    public void parseFormParam(String paramStr){
        String[] params = paramStr.split("&");
        for (String param : params) {
            String[] items = param.split("=");
            if(items.length==1){
                // a
                paramMap.put(items[0], null);
            } else {
                // a=1,  a=
                if(paramMap.containsKey(items[0])){
                    // 第二次添加同名参数值
                    List<String> value = paramMap.get(items[0]);
                    value.add(items[1]);
                } else {
                    // 第一次添加参数
                    List<String> value = new ArrayList<>();
                    value.add(items[1]);
                    paramMap.put(items[0], value);
                }
            }
        }
    }

    @Override
    public String toString() {
        return "HttpServletRequestImpl{" +
                "in=" + in +
                ", method='" + method + '\'' +
                ", requestURI='" + requestURI + '\'' +
                ", protocol='" + protocol + '\'' +
                ", headerMap=" + headerMap +
                '}';
    }

    private String readLine(InputStream in) throws IOException {
        StringBuffer line = new StringBuffer();
        while (true) {
            char c = (char) in.read();
            // window 系统的 换行 是 \r\n
            if (c != '\r') {
                line.append(c);
            } else {
                // 读掉 \n
                in.read();
                break;
            }
        }
        return line.toString();
    }


    @Override
    public InputStream getInputStream() {
        return in;
    }

    @Override
    public String getMethod() {
        return method;
    }

    @Override
    public String getRequestURI() {
        return requestURI;
    }

    @Override
    public String getProtocol() {
        return protocol;
    }

    @Override
    public String getHeader(String name) {
        return headerMap.get(name);
    }

    @Override
    public Cookie[] getCookies() {
        // Cookie: name=zhangsan; age=18; like=pp
        String cookie = getHeader("Cookie");
        List<Cookie> list = new ArrayList<>();
        if(cookie != null){
            for (String str : cookie.split("; ")) {
                String[] items = str.split("=");
                Cookie ck = new CookieImpl(items[0],items[1]);
                list.add(ck);
            }
        }
        return list.toArray(new Cookie[0]);
    }

    @Override
    public HttpSession getSession() {
        return session;
    }

    @Override
    public String getParameter(String name) {
        List<String> value = paramMap.get(name);
        if(value==null){
            return null;
        } else {
            return value.get(0);
        }
    }

    // 数组型参数 ?a=1&b=2&a=3
    @Override
    public String[] getParameterValues(String name) {
        List<String> value = paramMap.get(name);
        if(value==null){
            return null;
        } else {
            // 集合转数组
            return value.toArray(new String[0]);
        }
    }

    @Override
    public String getQueryString() {
        return queryString;
    }
}
